package com.itbaizhan.shopping_search_service.service;

import co.elastic.clients.elasticsearch.ElasticsearchClient;
import co.elastic.clients.elasticsearch.core.SearchResponse;
import co.elastic.clients.elasticsearch.core.search.CompletionSuggestOption;
import co.elastic.clients.elasticsearch.core.search.FieldSuggester;
import co.elastic.clients.elasticsearch.core.search.Suggester;
import co.elastic.clients.elasticsearch.core.search.Suggestion;
import co.elastic.clients.elasticsearch.indices.AnalyzeRequest;
import co.elastic.clients.elasticsearch.indices.AnalyzeResponse;
import co.elastic.clients.elasticsearch.indices.analyze.AnalyzeToken;
import com.itbaizhan.shopping_common.pojo.*;
import com.itbaizhan.shopping_common.service.SearchService;
import com.itbaizhan.shopping_search_service.repository.GoodsESRepository;
import lombok.SneakyThrows;
import org.apache.dubbo.config.annotation.DubboService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.elasticsearch.client.elc.ElasticsearchTemplate;
import org.springframework.data.elasticsearch.client.elc.NativeQuery;
import org.springframework.data.elasticsearch.core.suggest.response.Suggest;
import org.springframework.stereotype.Service;

import java.sql.Array;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

@DubboService
@Service
public class SearchServiceImpl implements SearchService {
    @Autowired
    private ElasticsearchClient client;
    @Autowired
    private GoodsESRepository goodsESRepository;
    @Autowired
    private ElasticsearchTemplate template;


    /**
     * 分词
     *
     * @param text   被分词的文本
     * @param analyzer 分词器
     * @return 分词结果
     */
    @SneakyThrows // 抛出已检查异常
    public List<String> analyze(String text, String analyzer) {
        // 分词请求
        AnalyzeRequest request = AnalyzeRequest.of(a ->
                a.index("goods").analyzer(analyzer).text(text)
        );
        // 发送分词请求，获取相应结果
        AnalyzeResponse response = client.indices().analyze(request);
        // 处理相应结果
        List<String> words = new ArrayList(); // 分词结果集合
        List<AnalyzeToken> tokens = response.tokens();
        for (AnalyzeToken token : tokens) {
            String term = token.token();// 分出的词
            words.add(term);
        }
        return words;
    }

    //es搜索自动补齐
    @SneakyThrows
    @Override
    public List<String> autoSuggest(String keyword) {
       //自动补齐查询条件
        Suggester suggester = Suggester.of(
                s -> s.suggesters("prefix_suggestion", FieldSuggester
                        .of(
                                fs -> fs.completion(
                                        cs ->cs.skipDuplicates(true)   //开启补齐结果去重
                                                .size(10)   //提示10个词
                                                .field("tags")  //在tags域中补齐
                                )
                        )
                        ).text(keyword));
       //2.自动补齐查询
        SearchResponse<Map> response =client.search(s -> s.index("goods").suggest(suggester), Map.class);
       //3. 处理查询结果
        Map resultMap = response.suggest();
        List<Suggestion> suggestionList = (List) resultMap.get("prefix_suggestion");
        Suggestion suggestion = suggestionList.get(0);
        List<CompletionSuggestOption> resultList = suggestion.completion().options();

        List<String> result = new ArrayList();
        for (CompletionSuggestOption completionSuggestOption : resultList) {
            String text = completionSuggestOption.text();
            result.add(text);
        }
        return result;
    }

    @Override
    public GoodsSearchResult search(GoodsSearchParam goodsSearchParam) {
      //1. 构造Es的构造条件

        //2.搜索

        //3.将查询结果封装为Mybatis-plus的Page对象

        //4.封装查询结果
        //4.1封装商品
        //4.2封装查询参数
        //4.3封装查询面板
        return null;
    }


    /**
     * 创建条件对象
     * @param goodsSearchParam
     * @return   封装好的查询条件
     */
    private NativeQuery buildQuery(GoodsSearchParam goodsSearchParam) {
      //1. 创建复杂查询条件对象

        //2. 如果查询条件有关键词,关键词可以匹配商品名,副标题,品牌字段,否则查询所有商品

        //3.如果查询条件有品牌,精准匹配品牌

        //4.如果查询条件有价格,则匹配价格

        //5.如果查询条件有规格项,则精准匹配规格项

        //6.添加分页条件

        //7.如果查询条件有排序,则添加排序条件

        //8.返回封装好的查询条件
        return null;
     }

    // 同步商品到es
    @Override
    public void syncGoodsToEs(GoodsDesc goodsDesc) {
        // 将商品详情对象转为GoodsES对象
        GoodsES goodsES = new GoodsES();
        goodsES.setId(goodsDesc.getId());
        goodsES.setGoodsName(goodsDesc.getGoodsName());
        goodsES.setCaption(goodsDesc.getCaption());
        goodsES.setPrice(goodsDesc.getPrice());
        goodsES.setBrand(goodsDesc.getBrand().getName());
        goodsES.setHeaderPic(goodsDesc.getHeaderPic());
       //商品类型集合
        ArrayList<String> productType = new ArrayList();
        productType.add(goodsDesc.getProductType1().getName());
        productType.add(goodsDesc.getProductType2().getName());
        productType.add(goodsDesc.getProductType3().getName());
        goodsES.setProductType(productType);
        //规格集合
        Map<String, List<String>> map = new HashMap<>();
        List<Specification> specifications = goodsDesc.getSpecifications();
      //遍历规格集合
       for (Specification specification : specifications) {
            //拿到规格项
            List<SpecificationOption> specificationOptions = specification.getSpecificationOptions();
          List<String> option = new ArrayList();
          for (SpecificationOption specificationOption : specificationOptions) {
              option.add(specificationOption.getOptionName());
          }
          map.put(specification.getSpecName(),option);
       }
       goodsES.setSpecification(map);
        // 关键字
        List<String> tags = new ArrayList();
        tags.add(goodsDesc.getBrand().getName()); //品牌名是关键字
        tags.addAll(analyze(goodsDesc.getGoodsName(),"ik_smart"));//商品名分词后为关键词
        tags.addAll(analyze(goodsDesc.getCaption(),"ik_smart"));//副标题分词后为关键词
        goodsES.setTags(tags);

        // 将GoodsES对象存入ES
        goodsESRepository.save(goodsES);

    }

    @Override
    public void delete(Long id) {

    }
}

